package com.android.qjpmc.widget.service;

import android.app.Activity;
import android.app.DownloadManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import androidx.fragment.app.FragmentActivity;

import com.android.qjpmc.widget.bean.UpdateApkInfo;
import com.android.qjpmc.widget.interfaces.DownLoadListener;
import com.android.qjpmc.widget.manager.UpdateApkManager;
import com.android.qjpmc.widget.mvvm.view.AppActivityManager;
import com.android.qjpmc.widget.utils.FileUtils;
import com.android.qjpmc.widget.utils.ToastUtils;

import java.io.File;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @Author zhangshuqi
 * @CreateTime 2018/4/12
 * @Describe
 */

public class DownloadService extends Service {
    private static final String TAG = DownloadService.class.getSimpleName();

    public static final int HANDLE_DOWNLOAD = 0x001;
    public static final String BUNDLE_KEY_DOWNLOAD_URL = "";
    public static final String BUNDLE_KEY_DOWNLOAD_FILENAME = "fileName";
    public static final String BUNDLE_KEY_DOWNLOAD_PATH = "filePath";
    public static final float UNBIND_SERVICE = 2.0F;

    private Activity activity;
    private DownloadBinder binder;
    private DownloadManager downloadManager;
    private DownloadChangeObserver downloadObserver;
    private BroadcastReceiver downLoadBroadcast;
    private ScheduledExecutorService scheduledExecutorService;

    //下载任务ID
    private long downloadId;
    private String downloadUrl;

    public Handler downLoadHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (mDownLoadListener != null && HANDLE_DOWNLOAD == msg.what) {
                //被除数可以为0，除数必须大于0
                if (msg.arg1 >= 0 && msg.arg2 > 0) {
                    mDownLoadListener.onProgress(msg.arg1 / (float) msg.arg2);
                }
            }
        }
    };

    private Runnable progressRunnable = new Runnable() {
        @Override
        public void run() {
            updateProgress();
        }
    };
    private DownloadManager.Request request;
    private String fileName;
    private DownLoadListener mDownLoadListener;
    private String filePath;

    @Override
    public void onCreate() {
        super.onCreate();
        binder = new DownloadBinder();
    }

    @Override
    public IBinder onBind(Intent intent) {
        downloadUrl = intent.getStringExtra(BUNDLE_KEY_DOWNLOAD_URL);
        fileName = intent.getStringExtra(BUNDLE_KEY_DOWNLOAD_FILENAME);
        filePath = intent.getStringExtra(BUNDLE_KEY_DOWNLOAD_PATH);

        return binder;
    }

    /**
     * 下载最新APK
     */
    private void download(String url, String fileName, String filePath) {
        downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
        downloadObserver = new DownloadChangeObserver();
        registerContentObserver();
        request = new DownloadManager.Request(Uri.parse(url));
        /**设置用于下载时的网络状态*/
        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
        /**设置通知栏是否可见*/
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);

        /**如果我们希望下载的文件可以被系统的Downloads应用扫描到并管理，
         我们需要调用Request对象的setVisibleInDownloadsUi方法，传递参数true.*/
        request.setVisibleInDownloadsUi(true);
        /**设置漫游状态下是否可以下载*/
        request.setAllowedOverRoaming(true);//漫游网络是否可以下载
        /**设置文件保存路径*/
        request.setDestinationInExternalPublicDir(filePath, fileName);
        /**将下载请求放入队列， return下载任务的ID*/
        downloadId = downloadManager.enqueue(request);

        registerBroadcast();
    }

    /**
     * 注册广播
     */
    private void registerBroadcast() {
        /**注册service 广播 1.任务完成时 2.进行中的任务被点击*/
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
        intentFilter.addAction(DownloadManager.ACTION_NOTIFICATION_CLICKED);
        registerReceiver(downLoadBroadcast = new DownLoadBroadcast(), intentFilter);
    }

    /**
     * 注销广播
     */
    private void unregisterBroadcast() {
        if (downLoadBroadcast != null) {
            unregisterReceiver(downLoadBroadcast);
            downLoadBroadcast = null;
        }
    }

    /**
     * 注册ContentObserver
     */
    private void registerContentObserver() {
        /** observer download change **/
        if (downloadObserver != null) {
            getContentResolver().registerContentObserver(Uri.parse("content://downloads/my_downloads"), false, downloadObserver);
        }
    }

    /**
     * 注销ContentObserver
     */
    private void unregisterContentObserver() {
        if (downloadObserver != null) {
            getContentResolver().unregisterContentObserver(downloadObserver);
        }
    }

    /**
     * 关闭定时器，线程等操作
     */
    private void close() {
        if (scheduledExecutorService != null && !scheduledExecutorService.isShutdown()) {
            scheduledExecutorService.shutdown();
        }

        if (downLoadHandler != null) {
            downLoadHandler.removeCallbacksAndMessages(null);
        }
    }

    /**
     * 发送Handler消息更新进度和状态
     */
    private void updateProgress() {
        int[] bytesAndStatus = getBytesAndStatus(downloadId);
        downLoadHandler.sendMessage(downLoadHandler.obtainMessage(HANDLE_DOWNLOAD, bytesAndStatus[0], bytesAndStatus[1], bytesAndStatus[2]));
    }

    /**
     * 通过query查询下载状态，包括已下载数据大小，总大小，下载状态
     *
     * @param downloadId
     * @return
     */
    private int[] getBytesAndStatus(long downloadId) {
        int[] bytesAndStatus = new int[]{
                -1, -1, 0
        };
        DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
        Cursor cursor = null;
        try {
            cursor = downloadManager.query(query);
            if (cursor != null && cursor.moveToFirst()) {
                //已经下载文件大小
                bytesAndStatus[0] = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
                //下载文件的总大小
                bytesAndStatus[1] = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
                //下载状态
                bytesAndStatus[2] = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return bytesAndStatus;
    }

    /**
     * 绑定此DownloadService的Activity实例
     *
     * @param activity
     */
    public void setTargetActivity(Activity activity) {
        this.activity = activity;
    }

    public void updateApk() {
/*
         RetrofitJsonManagerTest.getInstance().apiService.getUpdateApkInfo(2, "42").compose(RxJavaHttpManager.<UpdateApkInfo>applyTransformer()).subscribe(new CommonObserver<UpdateApkInfo>() {
            @Override
            public void onNext(UpdateApkInfo o) {
                super.onNext(o);
               // showUpdateDialogFragment(o);

            }


        });
*/

       /* UpdateApkInfo info = new UpdateApkInfo();
        info.url = "http://img.cooscene.com//app/beta/v1.0/beta1cooapp_version2.0_beta1.apk";
        info.version = "1.1";
        fileName = info.fileName = UpdateApkManager.getInstance().getFileName(info.version);
        filePath = info.filePath = FileUtils.APK_PATH;

        showUpdateDialogFragment(info);*/


    }

    private void showUpdateDialogFragment(final UpdateApkInfo info) {
        FragmentActivity fragmentActivity = AppActivityManager.getAppActivityManager().currentActivity();
        if (fragmentActivity == null) {
            return;
        }
        File apkFile = UpdateApkManager.getInstance().getApkFile(info.version);
        if (apkFile.exists()) {
            if (mDownLoadListener != null)
                mDownLoadListener.onSuccess(Uri.fromFile(apkFile), apkFile);
            return;
        }

//        UpdateApkDialogFragment updateDialogFragment = UpdateApkManager.getUpdateDialogFragment();
       // updateDialogFragment.show(fragmentActivity.getSupportFragmentManager());
/*
        updateDialogFragment.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                download(info.url, info.fileName, info.filePath);
            }
        });
*/
    }


    /**
     * 接受下载完成广播
     */
    private class DownLoadBroadcast extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            long downId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
            Uri downIdUri = downloadManager.getUriForDownloadedFile(downloadId);
            switch (intent.getAction()) {
                case DownloadManager.ACTION_DOWNLOAD_COMPLETE:
                    if (downloadId == downId && downId != -1 && downloadManager != null) {
                        DownloadManager.Query query = new DownloadManager.Query();
                        query.setFilterById(downloadId);//筛选下载任务，传入任务ID，可变参数
                        DownloadManager dManager = (DownloadManager) getApplicationContext().getSystemService(Context.DOWNLOAD_SERVICE);
                        Cursor c = dManager.query(query);
                        if (c.moveToFirst()) {
                            int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
                            switch (status) {
                                case DownloadManager.STATUS_PAUSED:
                                    if (mDownLoadListener != null)
                                        mDownLoadListener.onPaused();
                                    break;
                                case DownloadManager.STATUS_PENDING:
                                    if (mDownLoadListener != null)
                                        mDownLoadListener.onPending();
                                    break;
                                case DownloadManager.STATUS_RUNNING:
                                    if (mDownLoadListener != null)
                                        mDownLoadListener.onRunning();
                                    break;
                                case DownloadManager.STATUS_SUCCESSFUL:
                                    if (mDownLoadListener != null) {
                                        File file = new File(FileUtils.getDiskCacheDir() + "/" + filePath + "/" + fileName);
                                        mDownLoadListener.onSuccess(downIdUri, file);
                                    }
                                    break;
                                case DownloadManager.STATUS_FAILED:
                                    ToastUtils.showShort("下载失败,请重试");
                                    if (mDownLoadListener != null) {
                                        mDownLoadListener.onFailed();
                                    }
                                    break;
                            }

                        }

                    }

                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 监听下载进度
     */
    private class DownloadChangeObserver extends ContentObserver {

        public DownloadChangeObserver() {
            super(downLoadHandler);
            scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        }

        /**
         * 当所监听的Uri发生改变时，就会回调此方法
         *
         * @param selfChange 此值意义不大, 一般情况下该回调值false
         */
        @Override
        public void onChange(boolean selfChange) {
            scheduledExecutorService.scheduleAtFixedRate(progressRunnable, 0, 2, TimeUnit.SECONDS);
        }
    }

    public class DownloadBinder extends Binder {
        /**
         * 返回当前服务的实例
         *
         * @return
         */
        public DownloadService getService() {
            return DownloadService.this;
        }

    }

    public interface OnProgressListener {
        /**
         * 下载进度
         *
         * @param fraction 已下载/总大小
         */
        void onProgress(float fraction);
    }

    /**
     * 对外开发的方法
     *
     * @param downLoadListener
     */
    public void setOnDownLoadListener(DownLoadListener downLoadListener) {
        this.mDownLoadListener = downLoadListener;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterBroadcast();
        unregisterContentObserver();
        downLoadHandler = null;
    }
}
